Add reativa (OCaml/Melange) example implementations with a "Reativa" tab#8
Merged
Merged
Conversation
Add an OCaml/Melange setup to both workflows so the "Reativa" tab ships the real compiled bundle instead of the checked-in placeholder: - ci.yml: sets up OCaml 5.2, installs dune/melange/mlx, pins reativa, and runs `npm run reativa` so the .mlx examples are compiled and type-checked on every PR. - deploy-pages.yml: same, before the website build, so the published site renders the live reativa components. The Melange build stays out of the local `npm run build` (opam/melange aren't needed there); CI regenerates src/reativa.bundle.js (built = true) ahead of the Vite build, which scans it for Tailwind classes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqv9Uid5eY56AYzXPphg1c
CI surfaced `Error: Library "reativa" not found`: reativa's core library has no public_name, so it's a private dune library that can't be consumed as an installed opam package (only its own in-repo demo can use it). Consuming it via `opam pin` + `(libraries reativa)` never works. Build the examples the same way reativa's demo does — inside the reativa dune project. website/scripts/build-reativa.mjs clones reativa (pinned commit), drops the example dune + xpecs_reativa.mlx into a subdirectory of it (so the private `reativa` library and reativa.mlx_ppx resolve), runs dune build @melange, and bundles the emitted entry to src/reativa.bundle.js with esbuild. - Remove the standalone website/reativa/dune-project (reativa's own is used). - Replace the reativa:build/reativa:bundle npm scripts with the clone-based build-reativa.mjs, invoked by `npm run reativa`. - Drop `opam pin add reativa` from both workflows (private lib; the script clones it); keep the dune/melange/mlx install. - Scope the Tailwind @source for reativa sources to the top-level .mlx so it doesn't recurse into the .build/ clone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqv9Uid5eY56AYzXPphg1c
brnrdog
force-pushed
the
claude/xpecs-reasonml-reativa-q124yw
branch
from
July 23, 2026 19:03
b23e127 to
64d2d2e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A first proof of concept implementing a few Xpecs specs in OCaml with reativa — the fine-grained, signal-based UI library (the OCaml sibling of Xote) — and rendering them in the website alongside the existing ReScript + Xote examples in a new Reativa tab. The website stays on ReScript + Xote + Vite as-is.
Specs implemented (
website/reativa/xpecs_reativa.mlx):buttonbadgealertvisiblesignalcta-sectionBoth implementations render from the same design tokens (shared token-driven Tailwind classes), so they look identical — the point is to compare the two stacks side by side.
How it plugs in
website/reativa/is a self-contained Melange workspace (dune-project+dunewithmelange.emit+ themlxdialect), following reativa's own demo conventions.npm run reativa(inwebsite/) runsdune build @melange, then bundles the emitted ES module with esbuild intowebsite/src/reativa.bundle.js— a module exportingmount_example(specId, containerId),example_ids, andbuilt.website/src/ReativaExamples.resimports that bundle; theExampleBlockgains a Reativa tab next to Preview that imperatively mounts the example into a container<div>Xote renders (the reativa runtime owns that subtree).npm run build/dev(it needs opam + melange, the website otherwise doesn't). A checked-in placeholder bundle (built = false) keeps the site compiling and shows a build hint until the real bundle is generated.Building it on CI
Both workflows now set up OCaml 5.2, install
dune/melange/mlx, pinreativafrom git, and runnpm run reativabefore the website build:ci.yml— compiles and type-checks the.mlxon every PR.deploy-pages.yml— compiles the real bundle into the published site, so the Reativa tab renders the live components.Verified locally
vite buildsucceeds with the placeholder (import resolves; Tailwind scans the bundle).Not verified locally
The OCaml/Melange compile itself — this sandbox's network policy blocks the opam ecosystem (package tarball downloads 403), so the toolchain couldn't run here. The
.mlxis authored against reativa's verified demo patterns; CI is the first place it actually compiles, which is exactly what the CI wiring above is for. Expect possible small first-compile fixups.🤖 Generated with Claude Code
Generated by Claude Code